module ambrot
import StdEnv, japi

/* Mandelbrot fractal.  */

:: State = { fr::!Framer, quit::!Entry, 
             save::!Entry, canvas::!Canvas}

mandel zre zim m= loop 0 0.0 0.0
where
   loop it x y
     # it= it+1
     | it >= m = (m*11, m*13, m*17)
     # (x, y)= (x*x-y*y+zre, 2.0*x*y+zim)
     | x*x+y*y > 4.0= (it*11, it*13, it*17)
     | otherwise= loop it x y

mb xs xe ys ye cv js
  # (w, cv)= jgetwidth cv
    (h, cv)= jgetheight cv 
  = loop w h 1 1 cv js
where
  loop w h x y cv js
         # x= (x+1) rem w
         # y= if (x==0) ((y+1) rem h) y
         | x== w-1 && y == h-1= (cv, js)
         # zre= xs + (toReal x)* (xe-xs)/(toReal w)
         # zim= ys + (toReal y)*(ye-ys)/(toReal h)
         # cv= color (mandel zre zim 512) cv 
         # cv= jdrawpix (x, y) cv
         = loop w h x y cv js
             
Start world
  # (js, world) = begin_japi world
    (frm, js) = jnewFrame (WH 400 300) "Draw Things" js
    (cv, js) = jnewCanvas (XYWH 0 0 400 300) frm js
    (mnb, js) = jnewBar frm js
    (filemn, js) = jnewMenu  "File" mnb js 
    (sv, js) = jnewItem "Save" filemn js
    (qt, js) = jnewItem "Quit" filemn js
    (frm, js) = jshow frm js
    (cv, js) = mb -2.0 1.0 -1.0 1.0 cv js
    s= { fr= frm, quit= qt, save= sv, canvas=cv}
    js = loop s js
  = end_japi js world
where
  loop :: !State !JapiState -> JapiState
  loop s js
      # (na,js) = jnextaction  js
      | na== (act s.fr) || na== (act s.quit)= jquit js
      | na== (act s.save) 
           # img= jgetimage s.canvas
             (fname, js) = jfilesel s.fr "*.ppm" js
             (_, js) = jsaveppm img fname js 
           = loop s js
      = loop s js
 
 